package co.edu.uniandes.sd.interfaz;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.UIManager;

import co.edu.uniandes.sd.mundo.Archivo;
import co.edu.uniandes.sd.mundo.Nodo;

public class InterfazCliente extends JFrame implements Observer
{
	private PanelEncabezado panelEncabezado;

	private PanelPrincipal panelPrincipal;

	private BarraMenuCliente barraMenu;

	private PanelVerArchivos panelVerArchivos;

	private PanelBusqueda panelBusquedas;

	private PanelAgregarArchivo panelAgregarArchivo;

	private FileTreePanel panelArbol;

	private JSplitPane splitPaneArchivos;
	
	private Nodo nodo;

	private ArrayList<Archivo> archivos;
	
	private DialogoModificacion dialogoModificacion;
	
	private DialogoDescarga dialogoDescarga;
	
	public InterfazCliente(Nodo nodo) {
		this.nodo = nodo; 
		this.nodo.addObserver(this);
		archivos = this.nodo.darArchivos();
		setTitle("TUXTA");
		setLayout(new BorderLayout());
		setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		barraMenu = new BarraMenuCliente(this);
		setJMenuBar(barraMenu);
		setResizable(false);
		setSize(800, 500);
		setIconImage(Toolkit.getDefaultToolkit().getImage("data/tux.png"));
		
		panelEncabezado = new PanelEncabezado();
		add(panelEncabezado, BorderLayout.NORTH);

		panelPrincipal = new PanelPrincipal(this);

		panelVerArchivos = new PanelVerArchivos(this);
		panelBusquedas = new PanelBusqueda(this);
		panelAgregarArchivo = new PanelAgregarArchivo(this);
		panelArbol = new FileTreePanel(this, true, 0);

		panelPrincipal.addTab("Busquedas", panelBusquedas);
		splitPaneArchivos = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true,
				panelArbol, panelAgregarArchivo);
		splitPaneArchivos.setDividerLocation(200);
		panelPrincipal.addTab("Agregar Archivo", splitPaneArchivos);
		panelPrincipal.addTab("Ver Archivos", panelVerArchivos);


		add(panelPrincipal, BorderLayout.CENTER);

		dialogoModificacion = new DialogoModificacion(this);
		
		dialogoDescarga = new DialogoDescarga(this);
		cambiarEstado(false);
		centrar();
	}

	public void cambiarEstado( boolean param )
    {
        panelPrincipal.setEnabled(param);
        panelBusquedas.setEnabled(param);
        panelAgregarArchivo.setEnabled(param);
        panelArbol.setEnabled(param);
        panelEncabezado.setEnabled(param);
        getRootPane().setEnabled(param);
    }
	
	public void salir() {
		this.dispose();
	}

	/**
	 * Centra la ventana en la pantalla
	 */
	private void centrar() {
		Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
		int xEsquina = (screen.width - getWidth()) / 2;
		int yEsquina = (screen.height - getHeight()) / 2;
		setLocation(xEsquina, yEsquina);
	}	

	public void cambiarPerfil(String login, String clave, String nombre,
			String paisOrigen, String ciudad, Date fecha, String tipoDoc,
			int documento) {

	}

	public void dispose() {
		super.dispose();
		System.exit(0);
	}

	public void actualizarRutaArchivo(String darSeleccionTree) {
		panelAgregarArchivo.actualizarPath(darSeleccionTree);
	}

	public static void main(String[] args) {
		try {
			UIManager
					.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
		} catch (Exception e) {
			e.printStackTrace();
		}
		try{
			String user = JOptionPane.showInputDialog(null, "Ingrese su usuario");
			String pass = JOptionPane.showInputDialog(null, "Ingrese su contraseña");
			Nodo nodo = new Nodo(user, pass);
				
			InterfazCliente interfaz = new InterfazCliente(nodo);
			interfaz.setVisible(true);
			interfaz.cambiarEstado(true);
		}catch (Exception e) {
			JOptionPane.showMessageDialog(null,e.getMessage()+"\nLa aplicación se cerrara","Error",JOptionPane.ERROR_MESSAGE);
			e.printStackTrace();
		}
	}

	@Override
	public void update(Observable o, Object arg) 
	{
		if(arg instanceof ArrayList)
		{
			if(((ArrayList) arg).get(0) instanceof String)
			{
				actualizarListaResultados((ArrayList<String>)arg);
			}
			else
			{
				archivos = (ArrayList<Archivo>)arg;
				actualizarListaArchivos(archivos);
			}
		}else if(arg instanceof Nodo.ArchivoTamanio){
			Nodo.ArchivoTamanio at = (Nodo.ArchivoTamanio)arg;
			ArrayList<String> lista = new ArrayList();
			lista.add(at.getIdentificador()+":"+at.getTamanio());
			actualizarListaResultados(lista);
		}else if(arg instanceof String){
			if(arg.equals("INICIO_MODIFICACION")){
				System.out.println("lalalala");
				dialogoModificacion = new DialogoModificacion(this);
				dialogoModificacion.setMensaje("Obteniendo permisos");
				dialogoModificacion.setVisible(true);
			}else if(arg.equals("FIN_MODIFICACION")){
				//dialogoModificacion.setVisible(false);
			}else if(arg.equals("OBTENER_PERMISOS")){
				dialogoModificacion.setMensaje("Modificacion en progreso");				
			}else if(arg.equals("DESCARGA")){
				Nodo.EstadoDescarga estadoDescarga = nodo.darEstadoDescarga();
				switch (estadoDescarga){
				case LIBRE:
					if(dialogoDescarga.isActive()){
						dialogoDescarga.dispose();
					}
					break;
				case EN_PROCESO:
					dialogoDescarga.setMensaje("Descarga en proceso");
					dialogoDescarga.setVisible(true);
					break;
				case VERIFICANDO_FIRMA:
					dialogoDescarga.setMensaje("Verificando firma");
					dialogoDescarga.setVisible(true);
					break;
				case CANCELADA:
					if(dialogoDescarga.isActive()){
						dialogoDescarga.dispose();
					}
					JOptionPane.showMessageDialog(this, "La firma del documento no ha podido ser validada","Error validando firma",JOptionPane.ERROR_MESSAGE);
					break;
				case TERMINADA:
					if(dialogoDescarga.isActive()){
						dialogoDescarga.dispose();
					}
					JOptionPane.showMessageDialog(this, "Documento descargado satisfactoriamente","Descarga exitosa",JOptionPane.INFORMATION_MESSAGE);
					break;
				}
				
				
			}
		}
			
	}

	private void actualizarListaArchivos(ArrayList<Archivo> arg) {
		panelVerArchivos.actualizarListaArchivos(arg);
	}

	private void actualizarListaResultados(ArrayList<String> darArchivosBusqueda) {
		panelBusquedas.actualizarListaResultados(darArchivosBusqueda);
	}

	public void actualizarTamanioArchivo(long length) 
	{
		panelBusquedas.actualizarTamanioArchivo(length);
	}

	public void buscarPorContenido(String txtPalabraClave) {
		// TODO Auto-generated method stub
		nodo.buscarArchivoPorPalabrasClave(txtPalabraClave);
	}

	public void buscarPorIdentificador(String txtIdArchivo) {
		// TODO Auto-generated method stub
		nodo.descargarArchivoPorIdentificador(txtIdArchivo);		
		panelBusquedas.refresh();
	}

	public void buscarPorTamanio(String txtTamanioArchivo) {
		// TODO Auto-generated method stub
		nodo.buscarArchivoPorTamanio(txtTamanioArchivo.length());
	}

	public void agregarArchivo(String text, String id, String kw) 
	{
		ArrayList<String> kwArray = new ArrayList<String>();
		String [] kws = kw.split(","); 
		for(int i=0; i<kws.length; i++)
		{
			kwArray.add(kws[i]);
		}
		if(text.equals("")||id.equals("")||kw.equals(""))
        {
        	JOptionPane.showMessageDialog(this, "No ha diligenciado toda la informaci�n.", "Mensaje", JOptionPane.WARNING_MESSAGE);
        }
        else
        {
        	try {
				nodo.agregarArchivo(new File(text), id, kwArray);
				panelBusquedas.refresh();
				JOptionPane.showMessageDialog(this, "Se ha agregado el archivo correctamente.", "Mensaje", JOptionPane.INFORMATION_MESSAGE);
								
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
        }
	}

	public String darNombreNodo() {
		return nodo.getNombre();
	}

	public void actualizarTablaArchivos(String seleccion) 
	{
		ArrayList<Archivo> archivos2 = new ArrayList<Archivo>();
		if(panelPrincipal.getSelectedIndex()==2)
		{
			for(int i=0; i<archivos.size(); i++)
			{
				if(archivos.get(i).getArchivo().getParent().equals(seleccion))
				{
					archivos2.add(archivos.get(i));
				}
			}
			panelVerArchivos.actualizarListaArchivos(archivos2);
		}
	}

	public void descargarArchivo(Object selectedValue) 
	{
		nodo.descargarArchivoPorIdentificador(((String)selectedValue).split(":")[0]);
		panelBusquedas.refresh();
		JOptionPane.showMessageDialog(this, "Se ha descargado el archivo correctamente.", "Mensaje", JOptionPane.INFORMATION_MESSAGE);
	}
	
	public void modificarArchivo(String id){
		try{
			nodo.solicitarModificacionArchivo(id);
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void guardarEstado(){
		try{
			nodo.guardarEstadoAccion();
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void finalizarModificacion(){
		try{
			nodo.finalizarModificacion();
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void iniciarVisualizacionArhchivo(File file)
	{
		try {
			nodo.desEncriptarArchivo(file);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void finalizarVisualizacion(File file)
	{
		try {
			nodo.encriptarArchivo(file);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void login() 
	{
		String user = JOptionPane.showInputDialog(this, "Ingrese su usuario");
		String pass = JOptionPane.showInputDialog(this, "Ingrese su contraseña");
		nodo.setLoginInfo(user, pass);
		cambiarEstado(true);
	}
	
}
